import Data.List
import Data.Ord
import Data.Char	

primes :: [Integer]
primes = 2 : filter ( (==1) . length . primeFactors ) [3,5..]

primeFactors :: Integer -> [Integer]
primeFactors n = factor n primes
	where
	factor n (p:ps)
		| p*p > n		 = [n]
		| n `mod` p == 0 = p : factor ( n `div` p )	(p:ps)
		| otherwise		 = factor n ps
		
isPrime :: Integer -> Bool
isPrime n
	| n <= 1 	= False
	| otherwise =((length(primeFactors n)) == 1)

isnPanDigital :: Int -> String -> Bool
isnPanDigital n text
		| length text /= n 			= False
		| length (nub text) /= n 	= False
		| any (=='0') text			= False
		| maximum (map ((subtract (ord '0')).ord) text) /= n = False
		| otherwise					= True
		
isPanDigital :: String -> Bool
isPanDigital = (isnPanDigital 9)

panDigitalPrimes1 = filter (\x->let y = show x in (isnPanDigital (length y) y)) primes

pannDigitalNumbers :: Integer -> [Integer]
pannDigitalNumbers n = map read (map concat (permutations (map show [1..n])))

panDigitalNumbers :: [Integer]
panDigitalNumbers = concat $ map pannDigitalNumbers [2..9]

euler_041 = maximum $ filter isPrime panDigitalNumbers